#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
工具函数模块
提供一些共用的辅助函数
"""

import time
import numpy as np
import pandas as pd
import os
from datetime import datetime
from typing import Callable, Any, Dict, List, Tuple

def create_experiment_dir() -> str:
    """
    创建带时间戳的实验目录
    
    Returns:
        创建的实验目录路径
    """
    # 创建实验结果目录
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    experiment_dir = f"experiments/exp_{timestamp}"
    
    # 确保目录存在
    os.makedirs(experiment_dir, exist_ok=True)
    
    print(f"创建实验目录: {experiment_dir}")
    return experiment_dir

# 全局变量保存当前实验目录
EXPERIMENT_DIR = None

def get_experiment_dir() -> str:
    """
    获取当前实验目录，如果不存在则创建
    
    Returns:
        实验目录路径
    """
    global EXPERIMENT_DIR
    if EXPERIMENT_DIR is None:
        EXPERIMENT_DIR = create_experiment_dir()
    return EXPERIMENT_DIR

def timer(func: Callable) -> Callable:
    """
    函数执行时间计时装饰器
    
    Args:
        func: 要计时的函数
        
    Returns:
        包装后的函数
    """
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间: {end_time - start_time:.4f} 秒")
        return result
    return wrapper

def validate_data(data: pd.DataFrame, expected_columns: List[str]) -> bool:
    """
    验证数据框是否包含所需的列
    
    Args:
        data: 要验证的数据框
        expected_columns: 期望的列名列表
        
    Returns:
        是否包含所有期望的列
    """
    return all(col in data.columns for col in expected_columns)

def save_results(results: Dict[str, Any], filename: str) -> None:
    """
    保存结果到CSV文件
    
    Args:
        results: 结果字典
        filename: 输出文件名
    """
    # 确保保存到实验目录
    exp_dir = get_experiment_dir()
    full_path = os.path.join(exp_dir, filename)
    
    pd.DataFrame.from_dict(results, orient='index').transpose().to_csv(full_path, index=False)
    print(f"结果已保存至: {full_path}")

def normalize_objectives(objectives: np.ndarray) -> np.ndarray:
    """
    归一化目标函数值到[0,1]区间
    
    Args:
        objectives: 目标函数值数组
        
    Returns:
        归一化后的目标函数值
    """
    min_vals = np.min(objectives, axis=0)
    max_vals = np.max(objectives, axis=0)
    range_vals = max_vals - min_vals
    # 避免除以零
    range_vals[range_vals == 0] = 1.0
    
    return (objectives - min_vals) / range_vals 